package com.shlh.saas.service.impl;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shlh.saas.config.PaymentConfig;
import com.shlh.saas.entity.PaymentOrder;
import com.shlh.saas.entity.UserBalance;
import com.shlh.saas.entity.VipPackage;
import com.shlh.saas.entity.EmailPackage;
import com.shlh.saas.mapper.PaymentOrderMapper;
import com.shlh.saas.mapper.UserBalanceMapper;
import com.shlh.saas.mapper.UserMapper;
import com.shlh.saas.mapper.EmailPackageMapper;
import com.shlh.saas.service.PaymentOrderService;
import com.shlh.saas.service.RechargeRecordService;
import com.shlh.saas.service.UserBalanceService;
import com.shlh.saas.service.VipPackageService;
import com.shlh.saas.service.EmailPackageService;
import com.shlh.saas.util.WechatPayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * 支付订单服务实现类
 */
@Service
@Slf4j
public class PaymentOrderServiceImpl extends ServiceImpl<PaymentOrderMapper, PaymentOrder> implements PaymentOrderService {

    // 支付宝网关
    private static final String GATEWAY_URL = "https://openapi.alipay.com/gateway.do";
    private static final String SANDBOX_GATEWAY_URL = "https://openapi.alipaydev.com/gateway.do";
    private static final String FORMAT = "json";
    private static final String CHARSET = "UTF-8";
    private static final String SIGN_TYPE = "RSA2";
    
    @Autowired
    private PaymentConfig paymentConfig;
    
    @Autowired
    private UserBalanceService userBalanceService;
    
    @Autowired
    private RechargeRecordService rechargeRecordService;
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private UserBalanceMapper userBalanceMapper;
    
    @Autowired
    private VipPackageService vipPackageService;
    
    @Autowired
    private EmailPackageService emailPackageService;
    
    @Autowired
    private EmailPackageMapper emailPackageMapper;


    @Override
    @Transactional
    public PaymentOrder createPaymentOrder(Long userId, BigDecimal amount, Integer paymentType, 
                                          String packageType, Integer packagePoints, String packageDuration) {
        // 生成订单号
        String orderNo = generateOrderNo(userId);
        
        PaymentOrder paymentOrder = new PaymentOrder();
        paymentOrder.setUserId(userId);
        paymentOrder.setOrderNo(orderNo);
        paymentOrder.setAmount(amount);
        paymentOrder.setPaymentType(paymentType);
        paymentOrder.setStatus(0); // 未支付
        paymentOrder.setPackageType(packageType);
        paymentOrder.setPackagePoints(packagePoints);
        paymentOrder.setPackageDuration(packageDuration);
        paymentOrder.setCreateTime(LocalDateTime.now());
        paymentOrder.setUpdateTime(LocalDateTime.now());
        
        // 保存订单
        this.save(paymentOrder);
        
        // 生成支付二维码
        String qrCodeUrl = "";
        if (paymentType == 1) {
            qrCodeUrl = getWechatPayQrCode(orderNo);
        } else if (paymentType == 2) {
            qrCodeUrl = getAlipayPayQrCode(orderNo);
        }
        
        // 更新二维码URL
        if (qrCodeUrl != null && !qrCodeUrl.isEmpty()) {
            paymentOrder.setQrCodeUrl(qrCodeUrl);
            this.updateById(paymentOrder);
        }
        
        return paymentOrder;
    }

    @Override
    public String getWechatPayQrCode(String orderNo) {
        // 获取订单信息
        PaymentOrder order = getOrderByOrderNo(orderNo);
        if (order == null) {
            log.error("订单不存在: {}", orderNo);
            return null;
        }
        
        try {
            // 构建微信支付参数
            Map<String, String> params = new HashMap<>();
            params.put("appid", paymentConfig.getWechatPay().getAppId());
            params.put("mch_id", paymentConfig.getWechatPay().getMchId());
            params.put("nonce_str", WechatPayUtil.generateNonceStr());
            params.put("body", "会员充值-" + order.getPackageType());
            params.put("out_trade_no", order.getOrderNo());
            // 微信支付金额单位为分
            params.put("total_fee", String.valueOf(order.getAmount().multiply(new BigDecimal("100")).intValue()));
            params.put("spbill_create_ip", "127.0.0.1");
            params.put("notify_url", paymentConfig.getWechatPay().getNotifyUrl());
            params.put("trade_type", "NATIVE"); // 扫码支付
            
            // 生成签名
            String sign = WechatPayUtil.generateSign(params, paymentConfig.getWechatPay().getMchKey());
            params.put("sign", sign);
            
            // 调用统一下单接口
            String codeUrl = WechatPayUtil.createUnifiedOrder(params);
            
            if (codeUrl != null) {
                log.info("生成微信支付二维码成功: {}", codeUrl);
                return codeUrl;
            } else {
                log.error("生成微信支付二维码失败");
                return null;
            }
        } catch (Exception e) {
            log.error("生成微信支付二维码异常", e);
            return null;
        }
    }

    @Override
    public String getAlipayPayQrCode(String orderNo) {
        // 获取订单信息
        PaymentOrder order = getOrderByOrderNo(orderNo);
        if (order == null) {
            log.error("订单不存在: {}", orderNo);
            return null;
        }
        
        try {
            log.info("开始生成支付宝支付二维码，订单号: {}", orderNo);
            // 初始化AlipayClient
            String gatewayUrl = paymentConfig.getAlipay().isSandbox() ? SANDBOX_GATEWAY_URL : GATEWAY_URL;
            AlipayClient alipayClient = new DefaultAlipayClient(
                    gatewayUrl,
                    paymentConfig.getAlipay().getAppId(),
                    paymentConfig.getAlipay().getPrivateKey(),
                    FORMAT,
                    CHARSET,
                    paymentConfig.getAlipay().getAlipayPublicKey(),
                    SIGN_TYPE
            );
            
            log.info("支付宝配置信息: gatewayUrl={}, appId={}, privateKey长度={}, alipayPublicKey长度={}", 
                    gatewayUrl, paymentConfig.getAlipay().getAppId(), 
                    paymentConfig.getAlipay().getPrivateKey().length(),
                    paymentConfig.getAlipay().getAlipayPublicKey().length());
            
            // 使用电脑网站支付接口
            AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
            request.setReturnUrl(paymentConfig.getAlipay().getReturnUrl()); // 支付成功后跳转的页面
            request.setNotifyUrl(paymentConfig.getAlipay().getNotifyUrl());
            
            // 构建请求参数
            Map<String, String> bizContent = new HashMap<>();
            bizContent.put("out_trade_no", order.getOrderNo());
            bizContent.put("total_amount", order.getAmount().toString());
            bizContent.put("subject", "会员充值-" + order.getPackageType());
            bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY"); // 电脑网站支付产品码
            bizContent.put("store_id", "JLH_STORE");
            bizContent.put("body", "会员充值服务");
            bizContent.put("timeout_express", "90m");
            
            String bizContentJson = JSON.toJSONString(bizContent);
            log.info("支付宝请求参数: {}", bizContentJson);
            request.setBizContent(bizContentJson);
            
            // 调用支付宝接口获取支付表单
            String form = alipayClient.pageExecute(request).getBody();
            return form; // 返回表单，前端需要直接显示该表单而非生成二维码
        } catch (AlipayApiException e) {
            log.error("调用支付宝接口异常", e);
            return null;
        }
    }

    @Override
    @Transactional
    public boolean handleWechatPayNotify(Map<String, String> notifyData) {
        try {
            log.info("接收到微信支付回调: {}", notifyData);
            
            // 验证返回状态
            if (!"SUCCESS".equals(notifyData.get("return_code"))) {
                log.error("微信支付回调通知失败: {}", notifyData.get("return_msg"));
                return false;
            }
            
            // 验证签名
            boolean signValid = WechatPayUtil.verifySign(notifyData, paymentConfig.getWechatPay().getMchKey());
            if (!signValid) {
                log.error("微信支付回调签名验证失败");
                return false;
            }
            
            // 验证业务结果
            if (!"SUCCESS".equals(notifyData.get("result_code"))) {
                log.error("微信支付业务结果失败: {}", notifyData.get("err_code_des"));
                return false;
            }
            
            String orderNo = notifyData.get("out_trade_no");
            String transactionId = notifyData.get("transaction_id");
            
            PaymentOrder order = getOrderByOrderNo(orderNo);
            if (order == null) {
                log.error("订单不存在: {}", orderNo);
                return false;
            }
            
            // 判断金额是否一致
            BigDecimal notifyAmount = new BigDecimal(notifyData.get("total_fee")).divide(new BigDecimal(100));
            if (order.getAmount().compareTo(notifyAmount) != 0) {
                log.error("订单金额不匹配: {} != {}", order.getAmount(), notifyAmount);
                return false;
            }
            
            // 更新订单状态
            return updateOrderPaid(order, transactionId);
        } catch (Exception e) {
            log.error("处理微信支付回调失败", e);
            return false;
        }
    }

    @Override
    @Transactional
    public boolean handleAlipayNotify(Map<String, String> notifyData) {
        try {
            // 验证签名等信息
            // TODO: 实际项目中需要验证签名
            
            String orderNo = notifyData.get("out_trade_no");
            String tradeStatus = notifyData.get("trade_status");
            String transactionId = notifyData.get("trade_no");
            
            // 只处理支付成功的回调
            if (!"TRADE_SUCCESS".equals(tradeStatus)) {
                return true;
            }
            
            PaymentOrder order = getOrderByOrderNo(orderNo);
            if (order == null) {
                log.error("订单不存在: {}", orderNo);
                return false;
            }
            
            // 判断金额是否一致
            BigDecimal notifyAmount = new BigDecimal(notifyData.get("total_amount"));
            if (order.getAmount().compareTo(notifyAmount) != 0) {
                log.error("订单金额不匹配: {} != {}", order.getAmount(), notifyAmount);
                return false;
            }
            
            // 更新订单状态
            return updateOrderPaid(order, transactionId);
        } catch (Exception e) {
            log.error("处理支付宝回调失败", e);
            return false;
        }
    }

    @Override
    public PaymentOrder getOrderByOrderNo(String orderNo) {
        return baseMapper.selectByOrderNo(orderNo);
    }

    @Override
    @Transactional
    public boolean updateOrderPaid(PaymentOrder order, String transactionId) {
        if (order.getStatus() == 1) {
            log.info("订单已支付，无需重复处理: {}", order.getOrderNo());
            return true;
        }
        
        try {
            // 更新订单状态
            order.setStatus(1); // 已支付
            order.setTransactionId(transactionId);
            order.setPayTime(LocalDateTime.now());
            order.setUpdateTime(LocalDateTime.now());
            boolean updated = this.updateById(order);
            
            if (!updated) {
                log.error("更新订单状态失败: {}", order.getOrderNo());
                return false;
            }
            
            // 根据套餐类型处理不同的业务逻辑
            switch (order.getPackageType()) {
                case "VIP":
                    // 处理VIP套餐
                    handleVipPackage(order);
                    break;
                case "EMAIL":
                    // 处理邮件套餐
                    handleEmailPackage(order);
                    break;
                case "CUSTOM":
                    // 处理自定义充值
                    handleCustomRecharge(order);
                    break;
                default:
                    log.warn("未知的套餐类型: {}", order.getPackageType());
                    break;
            }
            
            return true;
        } catch (Exception e) {
            log.error("处理订单支付完成异常: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 处理VIP套餐
     */
    private void handleVipPackage(PaymentOrder order) {
        try {
            // 从订单中获取套餐ID
            Integer packageId = order.getPackagePoints(); // 使用packagePoints存储套餐ID
            
            if (packageId == null || packageId <= 0) {
                log.error("订单{}处理VIP套餐失败：无效的套餐ID", order.getOrderNo());
                return;
            }
            
            // 查询套餐信息
            VipPackage vipPackage = vipPackageService.getPackageById(Long.valueOf(packageId));
            if (vipPackage == null) {
                log.error("订单{}处理VIP套餐失败：找不到ID为{}的套餐", order.getOrderNo(), packageId);
                return;
            }
            
            log.info("订单{}对应的VIP套餐：{}, 等级：{}, 有效期：{}月", 
                    order.getOrderNo(), vipPackage.getName(), vipPackage.getLevel(), vipPackage.getDuration());
            
            // 更新用户VIP等级和到期时间
            Integer vipLevel = vipPackage.getLevel();
            Integer months = vipPackage.getDuration() != null ? vipPackage.getDuration() : 1;
            Integer exportQuota = vipPackage.getExportQuota() != null ? vipPackage.getExportQuota() : 0;
            Integer viewRecords = vipPackage.getViewRecords() != null ? vipPackage.getViewRecords() : 0;
            Integer reverseLookup = vipPackage.getReverseLookup() != null ? vipPackage.getReverseLookup() : 0;

            log.info("VIP套餐信息 - 等级: {}, 有效期: {}月, 导出条数: {}, 查看条数: {}, 反查条数: {}",
                    vipLevel, months, exportQuota, viewRecords, reverseLookup);
            
            // 调用userBalanceService更新VIP信息 - 此方法已经实现了额度叠加和时长取最长的逻辑
            boolean updated = userBalanceService.updateUserVipById(order.getUserId(), vipLevel, months, exportQuota, viewRecords, reverseLookup);
            
            if (updated) {
                log.info("用户ID={}的VIP信息更新成功", order.getUserId());
            } else {
                log.error("用户ID={}的VIP信息更新失败", order.getUserId());
            }
            
            // 创建充值记录
            createRechargeRecord(order, "VIP");
            
            log.info("处理订单{}的VIP套餐成功", order.getOrderNo());
        } catch (Exception e) {
            log.error("处理订单{}的VIP套餐异常", order.getOrderNo(), e);
        }
    }

    /**
     * 处理邮件套餐
     */
    private void handleEmailPackage(PaymentOrder order) {
        try {
            log.info("处理邮件套餐支付，订单号: {}, 用户ID: {}, 邮件数量: {}", 
                    order.getOrderNo(), order.getUserId(), order.getPackagePoints());
            
            // 1. 从邮件套餐表获取套餐详情
            Integer packageId = order.getPackagePoints();
            EmailPackage emailPackage = emailPackageMapper.selectById(packageId);
            
            if (emailPackage == null) {
                log.error("邮件套餐不存在，ID: {}", packageId);
                return;
            }
            
            // 2. 更新用户邮件配额 - 使用emailCount而不是email_count
            boolean quotaResult = userBalanceService.increaseEmailQuotaById(order.getUserId(), emailPackage.getEmailCount());
            
            // 3. 获取套餐等级和有效期
            Integer packageLevel = emailPackage.getLevel() != null ? emailPackage.getLevel() : 1;
            Integer duration = emailPackage.getDuration() != null ? emailPackage.getDuration() : 0;
            
            log.info("邮件套餐详情 - 名称: {}, 等级: {}, 有效期: {}天, 邮件数量: {}", 
                    emailPackage.getName(), packageLevel, duration, emailPackage.getEmailCount());
            
            // 4. 更新用户邮件套餐等级
            boolean levelResult = userBalanceService.updateEmailPackageLevelById(order.getUserId(), packageLevel);
            
            // 5. 处理有效期逻辑 - 按最长的计算
            if (duration > 0) {
                // 获取用户当前的邮件套餐信息
                UserBalance userBalance = userBalanceMapper.selectByUserId(order.getUserId());
                LocalDateTime newExpireTime = LocalDateTime.now().plusDays(duration);
                
                // 如果用户已有过期时间，比较哪个更长
                if (userBalance != null && userBalance.getEmailPackageExpireTime() != null) {
                    LocalDateTime currentExpireTime = userBalance.getEmailPackageExpireTime();
                    
                    // 只有当新的过期时间比当前过期时间更晚时，才更新
                    if (newExpireTime.isAfter(currentExpireTime)) {
                        log.info("新的过期时间({})比当前过期时间({})更长，更新为新的过期时间", 
                                newExpireTime, currentExpireTime);
                        userBalanceService.updateEmailPackageExpireTimeById(order.getUserId(), newExpireTime);
                    } else {
                        log.info("保留当前过期时间({}), 因为它比新的过期时间({})更长", 
                                currentExpireTime, newExpireTime);
                    }
                } else {
                    // 用户没有现有过期时间，直接设置
                    log.info("用户之前没有过期时间，设置为: {}", newExpireTime);
                    userBalanceService.updateEmailPackageExpireTimeById(order.getUserId(), newExpireTime);
                }
            }
            
            // 6. 创建充值记录
            createRechargeRecord(order, "EMAIL");
            
            log.info("邮件套餐处理完成 - 订单号: {}, 增加配额结果: {}, 更新等级结果: {}", 
                    order.getOrderNo(), quotaResult, levelResult);
        } catch (Exception e) {
            log.error("处理邮件套餐异常: {}", e.getMessage(), e);
        }
    }

    /**
     * 处理自定义充值
     */
    private void handleCustomRecharge(PaymentOrder order) {
        // 增加用户余额
        userBalanceService.addBalance(order.getUserId(), order.getAmount());
        
        // 创建充值记录
        createRechargeRecord(order, "CUSTOM");
    }

    /**
     * 创建充值记录
     */
    private void createRechargeRecord(PaymentOrder order, String type) {
        // 获取用户手机号
        String phone = userMapper.selectById(order.getUserId()).getPhone();
        
        // 获取用户当前余额
        UserBalance userBalance = userBalanceMapper.selectByUserId(order.getUserId());
        BigDecimal afterAmount = userBalance != null ? userBalance.getCashBalance() : order.getAmount();
        
        // 支付方式
        String payMethod = order.getPaymentType() == 1 ? "WECHAT" : "ALIPAY";
        
        // 创建充值记录
        rechargeRecordService.createRecord(
                phone,
                type,
                order.getAmount(),
                afterAmount,
                "在线充值-" + order.getPackageType(),
                payMethod,
                order.getPackagePoints()
        );
    }

    @Override
    public String generateOrderNo(Long userId) {
        // 生成订单号：时间戳 + 用户ID后4位 + 随机数
        String timestamp = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now());
        String userIdStr = String.format("%04d", userId % 10000);
        String random = String.format("%04d", (int)(Math.random() * 10000));
        return timestamp + userIdStr + random;
    }
} 